package com.wswy.wzcx.ui.user

import android.animation.ObjectAnimator
import android.arch.lifecycle.Observer
import android.graphics.Color
import android.os.Bundle
import android.os.Handler
import android.support.v4.content.ContextCompat
import android.text.Editable
import android.text.InputFilter
import android.text.TextUtils
import android.text.method.DigitsKeyListener
import android.text.method.HideReturnsTransformationMethod
import android.text.method.LinkMovementMethod
import android.text.method.PasswordTransformationMethod
import android.view.View
import android.view.animation.AnimationUtils
import android.view.inputmethod.EditorInfo
import com.blankj.utilcode.util.KeyboardUtils
import com.che.libcommon.utils.ToastUtils
import com.wswy.wzcx.R
import com.wswy.wzcx.module.base.gone
import com.wswy.wzcx.module.base.invisible
import com.wswy.wzcx.module.base.onClick
import com.wswy.wzcx.module.validator.ValidatorResult
import com.wswy.wzcx.statistics.StatisticsId
import com.wswy.wzcx.ui.other.PhoneTextWatcher
import com.wswy.wzcx.ui.other.TextWatcherIMPL
import com.wswy.wzcx.widget.utils.TextSizeProperty
import io.reactivex.Flowable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.subscribers.ResourceSubscriber
import kotlinx.android.synthetic.main.fragment_login.*
import java.util.concurrent.TimeUnit

/**
 * 登录
 */
class LoginFragment : BaseVerifyFragment() {

    private companion object {
        private const val TAG = "LoginFragment"
    }

    override fun getContentLayoutId(): Int {
        return R.layout.fragment_login
    }


    private var tabPwdStatus = false

    private lateinit var phoneLayoutController: PhoneLayoutController

    private var smsCodeDisposable: ResourceSubscriber<Long>? = null

    private val handler = Handler()

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)

        loginHolderViewModel = provideViewModelFromActivity(LoginHolderViewModel::class.java)
        loginHolderViewModel.stepState.type = LoginHolderViewModel.TYPE_LOGIN

        //切换密码登录
        tv_pwd_login.onClick {

            if (!tabPwdStatus){

                sendClickEvent(StatisticsId.u_dl_mm_tab)

                tv_pwd_login.setTextColor(ContextCompat.getColor(it.context,R.color.textColorPrimary))
                tv_phone_login.setTextColor(ContextCompat.getColor(it.context,R.color.textColorPrimary_40))

                ObjectAnimator.ofFloat(tv_pwd_login, TextSizeProperty.TEXTSIZE,18f,24f).setDuration(100).start()

                ObjectAnimator.ofFloat(tv_phone_login, TextSizeProperty.TEXTSIZE,24f,18f).setDuration(100).start()

                tabPwdStatus = true

                showPwdLogin()
            }

        }

        //点击切换手机验证码登录
        tv_phone_login.onClick {

            if (tabPwdStatus){

                sendClickEvent(StatisticsId.u_dl_yzm_tab)

                tv_pwd_login.setTextColor(ContextCompat.getColor(it.context,R.color.textColorPrimary_40))
                tv_phone_login.setTextColor(ContextCompat.getColor(it.context,R.color.textColorPrimary))

                ObjectAnimator.ofFloat(tv_pwd_login, TextSizeProperty.TEXTSIZE,24f,18f).setDuration(100).start()

                ObjectAnimator.ofFloat(tv_phone_login, TextSizeProperty.TEXTSIZE,18f,24f).setDuration(100).start()

                tabPwdStatus = false

                showPhoneLogin()
            }
        }

        phoneLayoutController = PhoneLayoutController(layout_phone,et_phone,img_et_phone_action)

        et_phone.addTextChangedListener(object :TextWatcherIMPL(){
            override fun afterTextChanged(s: Editable?) {
                super.afterTextChanged(s)
                inputCheck()
            }
        })


        et_line2.setOnFocusChangeListener { v, hasFocus ->

            if (hasFocus){
                //检查输入到手机号
                val phone = PhoneTextWatcher.getRealPhoneNumber(et_phone)

                if (phone?.length != 11){
                    layout_phone.error = "请输入11位手机号"
                }else{
                    layout_phone.error = null
                }

            }

        }

        //显示 隐藏 密码
        img_et_line2_action.onClick {

            it.isActivated = !it.isActivated

            if (it.isActivated){
                et_line2.transformationMethod = HideReturnsTransformationMethod.getInstance()
            }else{
                et_line2.transformationMethod = PasswordTransformationMethod.getInstance()
            }

            et_line2.setSelection(et_line2.text?.length?:0)

        }

        et_line2.addTextChangedListener(object : TextWatcherIMPL(){
            override fun afterTextChanged(s: Editable?) {
                super.afterTextChanged(s)
                inputCheck()
            }
        })

        //获取验证码
        tv_fetch_code.onClick {

            KeyboardUtils.hideSoftInput(et_phone)

            val phone = PhoneTextWatcher.getRealPhoneNumber(et_phone)
            if (phone.isNullOrEmpty()){
                ToastUtils.showText("请输入手机号")
                return@onClick
            }

            if(phone.length != 11){
                ToastUtils.showText("请输入完整手机号")
                return@onClick
            }

            sendClickEvent(StatisticsId.u_dl_yzm_send_click)

            tv_fetch_code.isClickable = false

            lockLoad()

            startGVerify()
        }

        //忘记密码
        tv_forget_pwd.onClick {
            sendClickEvent(StatisticsId.u_dl_wjmm)

            loginHolderViewModel.clickEvent(LoginHolderViewModel.CLICK_FORGET_PWD)
        }
        tv_service_protocol.highlightColor = Color.TRANSPARENT
        tv_service_protocol.movementMethod = LinkMovementMethod.getInstance()
        tv_service_protocol.text = LoginHelper.getServiceString(requireContext())

        //隐私协议
        cb_agree_protocol.setOnCheckedChangeListener { _, isChecked ->
            inputCheck()
        }

        //登录
        ll_btn_login.onClick {
            if (!cb_agree_protocol.isChecked) {
                val shake = AnimationUtils.loadAnimation(context,R.anim.anim_input)
                ll_service_layout.startAnimation(shake)
                ToastUtils.showText("请勾选同意《用户协议》及《隐私政策》")
                return@onClick
            }

            val phone = PhoneTextWatcher.getRealPhoneNumber(et_phone)
            val pwd = et_line2.text?.toString()
            if (phone.isNullOrEmpty()){
                ToastUtils.showText("请输入手机号")
                return@onClick
            }

            if (pwd.isNullOrEmpty()){
                ToastUtils.showText("请输入密码")
                return@onClick
            }

            doLogin(phone,pwd)

        }

        //微信登录
        img_wechat.setOnClickListener {
            sendClickEvent(StatisticsId.u_wechat)
            loginHolderViewModel.stepState.resetValue()
            loginHolderViewModel.clickEvent(LoginHolderViewModel.CLICK_WECHAT_LOGIN)
        }

        if (loginHolderViewModel.oneKeyLogin){
            ll_3th_login.gone()
            ll_service_layout.invisible()
            cb_agree_protocol.isChecked = true
        }

        showPhoneLogin()

        KeyboardUtils.showSoftInput(et_phone)
        listenData()
    }

    override fun lockLoad() {
        super.lockLoad()

//        ll_btn_login.isClickable = false
        tv_fetch_code.isEnabled = false
        tv_fetch_code.isClickable = false
//
//        et_phone.isFocusable = false
    //        et_phone.isFocusableInTouchMode = false
//
//        et_line2.isFocusable = false
//        et_line2.isFocusableInTouchMode = false

    }

    override fun unlockLoad() {
        super.unlockLoad()

//        et_phone.isFocusable = true
//        et_phone.isFocusableInTouchMode = true
//
//        et_line2.isFocusable = true
//        et_line2.isFocusableInTouchMode = true
//
        kotlin.runCatching {
            tv_fetch_code.isClickable = true
            tv_fetch_code.isEnabled = true
        }

//
//        ll_btn_login.isClickable = true
    }

    /** ----- 短信验证码 */
    override fun onSending() {
        super.onSending()
        lockLoad()
    }

    override fun onSendSuccess() {
        super.onSendSuccess()

        sendClickEvent(StatisticsId.u_dl_yzm_send_done)

        unlockLoad()
        startTrack()
        ToastUtils.showText("验证码已发送")
        et_line2.requestFocus()
        KeyboardUtils.showSoftInput(et_line2)
    }

    override fun onSendFail(msg: String?) {
        super.onSendFail(msg)
        unlockLoad()
        ToastUtils.showText(msg)
    }

    /** --- 人机验证 **/
    override fun onGVerifySuccess(ticket: ValidatorResult) {
        super.onGVerifySuccess(ticket)

        val phone =PhoneTextWatcher.getRealPhoneNumber(et_phone)
        loginHolderViewModel.sendSMSVerify(phone, ticket)

    }

    override fun onGVerifyError() {
        super.onGVerifyError()
        unlockLoad()

    }

    private fun doLogin(phone:String,pwd:String){

        handler.removeCallbacksAndMessages(null)

        KeyboardUtils.hideSoftInput(et_phone)

        loginHolderViewModel.doLogin(phone,pwd,tabPwdStatus)

    }

    private fun listenData(){


        loginHolderViewModel.getUserLoginLiveData().observe(this, Observer {

            it?.runCatching {

                if (isHidden){
                    return@runCatching
                }

                if(inLoading()){

                    ll_btn_login.loading("登录中...")

                    lockLoad()

                }else{

                    if (isOk() && data != null){

                        if (tabPwdStatus){
                            sendClickEvent(StatisticsId.u_dl_mm_done)
                        }else{
                            sendClickEvent(StatisticsId.u_dl_yzm_done)
                        }

                        ll_btn_login.success("登录成功"){

                            handler.postDelayed({
                                loginHolderViewModel.setUserLogined(data)
                            },500)

                        }
                    }else{

                        if (tabPwdStatus){
                            sendClickEvent(StatisticsId.u_dl_mm_fail)
                        }else{
                            sendClickEvent(StatisticsId.u_dl_yzm_fail)
                        }


                        ll_btn_login.fail("登录失败"){

                            handler.removeCallbacksAndMessages(null)
                            handler.postDelayed({

                                kotlin.runCatching {
                                    context?.let {
                                        ll_btn_login?.normal(getString(R.string.login))
                                    }
                                    unlockLoad()
                                }
                                
                            },2000)

                        }

                        ToastUtils.showText(message)
                    }

                }
            }
        })


    }


    override fun onDetach() {
        super.onDetach()
        handler.removeCallbacksAndMessages(null)
    }

    private fun showPwdLogin(){
        tv_fetch_code.visibility = View.GONE
        ll_btn_login.normal(getString(R.string.login))
        img_et_line2_action.isActivated = false

        et_line2.filters = arrayOf(InputFilter.LengthFilter(16))
        et_line2.text = null
        et_line2.keyListener = null
        et_line2.inputType = EditorInfo.TYPE_CLASS_TEXT or EditorInfo.TYPE_TEXT_VARIATION_PASSWORD

        layout_line2.hint = "密码"
    }

    private fun showPhoneLogin(){

        tv_fetch_code.visibility = View.VISIBLE
        ll_btn_login.normal(getString(R.string.login))
        //ed_line2.setHint(R.string.input_message_ver_code)
        et_line2.filters = arrayOf(InputFilter.LengthFilter(8))
        et_line2.text = null
        et_line2.inputType = EditorInfo.TYPE_CLASS_NUMBER

        et_line2.keyListener = DigitsKeyListener.getInstance("1234567890")

        layout_line2.hint = getString(R.string.input_message_ver_code)
    }

    //输入检测
    private fun inputCheck() {
        ll_btn_login.isEnabled = false
        val text = PhoneTextWatcher.getRealPhoneNumber(et_phone)
        //手机号输入正确
        val phone = !TextUtils.isEmpty(text) && text?.length == 11

        val line2Value = et_line2.text

        var line2 = false
        if (phone){

            line2 = !TextUtils.isEmpty(line2Value) && line2Value?.length?:0 >= 4

        }

        ll_btn_login.normal(getString(R.string.login))

        //账号密码 登录
        if (tabPwdStatus){
            //可现实
            if (TextUtils.isEmpty(line2Value)){
                img_et_line2_action.visibility = View.GONE
            }else{
                img_et_line2_action.visibility = View.VISIBLE
            }
        }else{
            img_et_line2_action.visibility = View.GONE
        }

        ll_btn_login.isEnabled = phone && line2

    }

    override fun onHiddenChanged(hidden: Boolean) {
        super.onHiddenChanged(hidden)
        if(hidden){
            KeyboardUtils.hideSoftInput(et_phone)
            cancelTrack()
        }else{
            resetViewStatus()
            KeyboardUtils.showSoftInput(et_phone)
        }

    }

    private fun resetViewStatus(){

        unlockLoad()

        tv_fetch_code.setText(R.string.fetch_ver_code)
        tv_fetch_code.isEnabled = true

        et_phone.text = null

        et_line2.text = null

        ll_btn_login.normal(getString(R.string.login))


        loginHolderViewModel.stepState.resetValue()
    }


    private fun startTrack(){

        cancelTrack()

        smsCodeDisposable = object :ResourceSubscriber<Long>(){
            override fun onComplete() {
                tv_fetch_code.isClickable = true
                tv_fetch_code.isEnabled = true
                tv_fetch_code.setText(R.string.fetch_ver_code)
            }

            override fun onNext(t: Long) {

                tv_fetch_code.isEnabled = false
                tv_fetch_code.isClickable = false
                tv_fetch_code.text = getString(R.string.captcha_timer,59-t)

            }
            override fun onError(t: Throwable?) {
                ToastUtils.showError(t)
            }

        }

        Flowable.intervalRange(0, 59, 0, 1, TimeUnit.SECONDS)
                .subscribeOn(AndroidSchedulers.mainThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(smsCodeDisposable)
    }

    private fun cancelTrack(){
        smsCodeDisposable?.dispose()
        smsCodeDisposable = null
    }

    override fun onDestroyView() {
        super.onDestroyView()
        cancelTrack()
    }

    override fun onDestroy() {
        super.onDestroy()
        cancelTrack()
    }
}